/**
 * Copyright 2024-2024 Huawei Technologies Co., Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef FRAMEWORK_HCL_HIAI_MR_ND_TENSOR_BUFFER_H
#define FRAMEWORK_HCL_HIAI_MR_ND_TENSOR_BUFFER_H
#include "c/hiai_c_api_export.h"
#include "hiai_types.h"
#include "hiai_base_types.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 根据tensor的描述信息申请设备内存
 *
 * 申请的{@link HIAI_MR_NDTensorBuffer}指针实例中包含了tensor的描述、申请到的内存的地址等信息，可使用下列get方法获取。
 * {@link HIAI_MR_NDTensorBuffer_GetNDTensorDesc}
 * {@link HIAI_MR_NDTensorBuffer_GetData}
 * {@link HIAI_MR_NDTensorBuffer_GetSize}
 *
 * 设备内存中无数据，需使用{@link HIAI_MR_NDTensorBuffer_GetData}方法获取到申请到的内存地址，
 * 根据需要写入模型推理时的输入数据或读取模型的输出数据。
 *
 * {@link HIAI_MR_NDTensorBuffer}不使用时，使用{@link HIAI_MR_NDTensorBuffer_Destroy}进行销毁，否则将造成内存泄漏。
 *
 * @param [in] desc {@link HIAI_NDTensorDesc}指针实例，非空，否则返回空指针
 * @return 成功时返回{@link HIAI_MR_NDTensorBuffer}指针实例，失败返回空指针
 * @see HIAI_MR_NDTensorBuffer_Destroy
 */
AICP_C_API_EXPORT HIAI_MR_NDTensorBuffer* HIAI_MR_NDTensorBuffer_CreateFromNDTensorDesc(const HIAI_NDTensorDesc* desc);

/**
 * @brief 根据HIAI_NDTensorDesc和指定的大小申请设备内存
 *
 * 本方法申请的内存大小与size相同,建议根据实际需要申请。{@link HIAI_MR_NDTensorBuffer}不使用时，使用
 * {@link HIAI_MR_NDTensorBuffer_Destroy}进行销毁，否则将造成内存泄漏。
 *
 * @param [in] desc {@link HIAI_NDTensorDesc}指针实例，非空，否则返回空指针
 * @param [in] size 指定申请内存的大小，以字节为单位，取值范围(0，INT_MAX]
 * @return 成功时返回{@link HIAI_MR_NDTensorBuffer}指针实例，失败返回空指针
 * @see HIAI_MR_NDTensorBuffer_Destroy
 */
AICP_C_API_EXPORT HIAI_MR_NDTensorBuffer* HIAI_MR_NDTensorBuffer_CreateFromSize(
    const HIAI_NDTensorDesc* desc, size_t size);

/**
 * @brief 根据HIAI_NDTensorDesc和图片格式申请设备内存
 *
 * 本方法申请的内存大小与图片的format相关，建议根据实际需要申请。{@link HIAI_MR_NDTensorBuffer}不使用时，使用
 * {@link HIAI_MR_NDTensorBuffer_Destroy}进行销毁，否则将造成内存泄漏。
 *
 * @param [in] desc {@link HIAI_NDTensorDesc}指针实例，非空，否则返回空指针
 * @param [in] format {@link HIAI_ImageFormat}图片格式
 * @return 成功时返回{@link HIAI_MR_NDTensorBuffer}指针实例，失败返回空指针
 */
AICP_C_API_EXPORT HIAI_MR_NDTensorBuffer* HIAI_MR_NDTensorBuffer_CreateFromFormat(
    const HIAI_NDTensorDesc* desc, HIAI_ImageFormat format);

/**
 * @brief 根据HIAI_NDTensorDesc申请设备内存，同时将data和dataSize写入tensor数据
 *
 * 传入的数据大小需与{@link HIAI_MR_NDTensorBuffer_GetSize}计算出的大小一致，创建{@link HIAI_MR_NDTensorBuffer}成功后，data的内存可释放。
 * {@link HIAI_MR_NDTensorBuffer}不使用时，使用{@link HIAI_MR_NDTensorBuffer_Destroy}进行销毁，否则将造成内存泄漏。
 *
 * @param [in] desc {@link HIAI_NDTensorDesc}指针实例，非空，否则返回空指针
 * @param [in] data tensor的数据地址，非空，否则返回空指针
 * @param [in] dataSize tensor的数据大小，大于0，否则返回空指针
 * @return 成功时返回{@link HIAI_MR_NDTensorBuffer}指针实例，失败返回空指针
 */
AICP_C_API_EXPORT HIAI_MR_NDTensorBuffer* HIAI_MR_NDTensorBuffer_CreateFromBuffer(
    const HIAI_NDTensorDesc* desc, const void* data, size_t dataSize);

/**
 * @brief 根据HIAI_NDTensorDesc和HIAI_NativeHandle创建HIAI_MR_NDTensorBuffer指针实例
 *
 * 本方法用于内存的零拷贝，即复用buffer_handle_t的内存，详细请见{@link HIAI_NativeHandle}。
 * {@link HIAI_MR_NDTensorBuffer}不使用时，使用{@link HIAI_MR_NDTensorBuffer_Destroy}进行销毁，否则将造成内存泄漏。
 *
 * @param [in] desc {@link HIAI_NDTensorDesc}指针实例，非空，否则返回空指针
 * @param [in] handle {@link HIAI_NativeHandle}指针实例，非空，否则返回空指针
 * @return 成功时返回{@link HIAI_MR_NDTensorBuffer}指针实例，失败返回空指针
 * @see HIAI_MR_NDTensorBuffer_Destroy
 */
AICP_C_API_EXPORT HIAI_MR_NDTensorBuffer* HIAI_MR_NDTensorBuffer_CreateFromNativeHandle(
    const HIAI_NDTensorDesc* desc, const HIAI_NativeHandle* handle);

/**
 * @brief 根据HIAI_NDTensorDesc和HIAI_NativeHandle创建HIAI_MR_NDTensorBuffer指针实例
 *
 * 本方法用于内存的零拷贝，即复用buffer_handle_t的内存，详细请见{@link HIAI_NativeHandle}。
 * {@link HIAI_MR_NDTensorBuffer}不使用时，使用{@link HIAI_MR_NDTensorBuffer_Destroy}进行销毁，否则将造成内存泄漏。
 * 与HIAI_MR_NDTensorBuffer_CreateFromNativeHandle区别为System进程专用，内存fd不在服务端注册。
 *
 * @param [in] desc {@link HIAI_NDTensorDesc}指针实例，非空，否则返回空指针
 * @param [in] handle {@link HIAI_NativeHandle}指针实例，非空，否则返回空指针
 * @return 成功时返回{@link HIAI_MR_NDTensorBuffer}指针实例，失败返回空指针
 * @see HIAI_MR_NDTensorBuffer_Destroy
 */
AICP_C_API_EXPORT HIAI_MR_NDTensorBuffer* HIAI_MR_NDTensorBuffer_CreateFromNativeHandleForSystemProcess(
    const HIAI_NDTensorDesc* desc, const HIAI_NativeHandle* handle);

/**
 * @brief 查询HIAI_MR_NDTensorBuffer中的tensor的描述信息
 *
 * @param [in] tensorBuffer {@link HIAI_MR_NDTensorBuffer}指针实例，非空，否则返回空指针
 * @return 成功时返回{@link HIAI_NDTensorDesc}指针实例，失败时返回空指针
 */
AICP_C_API_EXPORT HIAI_NDTensorDesc* HIAI_MR_NDTensorBuffer_GetNDTensorDesc(const HIAI_MR_NDTensorBuffer* tensorBuffer);

/**
 * @brief 查询HIAI_MR_NDTensorBuffer中的内存大小
 *
 * @param [in] tensorBuffer {@link HIAI_MR_NDTensorBuffer}指针实例，非空，否则返回0
 * @return 成功时返回内存大小，失败时返回0
 */
AICP_C_API_EXPORT size_t HIAI_MR_NDTensorBuffer_GetSize(const HIAI_MR_NDTensorBuffer* tensorBuffer);

/**
 * @brief 查询HIAI_MR_NDTensorBuffer中的内存地址
 *
 * @param [in] tensorBuffer {@link HIAI_MR_NDTensorBuffer}指针实例，非空，否则返回空指针
 * @return 成功时返回内存地址，失败时返回空指针
 */
AICP_C_API_EXPORT void* HIAI_MR_NDTensorBuffer_GetData(const HIAI_MR_NDTensorBuffer* tensorBuffer);

/**
 * @brief 查询NDTensorBuffer中的文件描述符
 *
 * @param [in] tensorBuffer {@link HIAI_MR_NDTensorBuffer}指针实例，非空，否则返回-1
 * @return 返回NDTensorBuffer中的文件描述符
 */
AICP_C_API_EXPORT int32_t HIAI_MR_NDTensorBuffer_GetFd(const HIAI_MR_NDTensorBuffer* tensorBuffer);

/**
 * @brief 销毁HIAI_MR_NDTensorBuffer指针实例
 *
 * 销毁由HIAI_MR_NDTensorBuffer_Create相关的接口创建的{@link HIAI_MR_NDTensorBuffer}指针实例，传入指针的引用即可。若不调用，将造成内存泄漏。
 * 如果tensorBuffer或者*tensorBuffer为空指针时，直接返回，不执行任何操作。
 *
 * @param [in] tensorBuffer {@link HIAI_MR_NDTensorBuffer}指针实例的引用
 */
AICP_C_API_EXPORT void HIAI_MR_NDTensorBuffer_Destroy(HIAI_MR_NDTensorBuffer** tensorBuffer);

/**
 * @brief 为HIAI_MR_NDTensorBuffer设置cache status
 *
 * 为传入的tensorBuffer指针实例设置对应的cache status，若不调用，则tensorBuffer将按照默认的status进行后面的流程。
 * 如果tensorBuffer或者*tensorBuffer为空指针时，直接返回，不执行任何操作。
 *
 * @param [in] tensorBuffer {@link HIAI_MR_NDTensorBuffer}指针实例的引用
 * @param [in] cacheStatus 设置的cache status参数
 */
AICP_C_API_EXPORT void HIAI_MR_NDTensorBuffer_SetCacheStatus(HIAI_MR_NDTensorBuffer* tensorBuffer, uint8_t cacheStatus);

/**
 * @brief 获取HIAI_MR_NDTensorBuffer的cache status
 *
 * 获取HIAI_MR_NDTensorBuffer的cache status。
 * 如果tensorBuffer或者*tensorBuffer为空指针时，返回0。
 *
 * @param [in] tensorBuffer {@link HIAI_MR_NDTensorBuffer}指针实例的引用
 * @return 返回NDTensorBuffer中的cache status
 */
AICP_C_API_EXPORT uint8_t HIAI_MR_NDTensorBuffer_GetCacheStatus(const HIAI_MR_NDTensorBuffer* tensorBuffer);

#ifdef __cplusplus
}
#endif

#endif // FRAMEWORK_HCL_HIAI_MR_ND_TENSOR_BUFFER_H
